package com.bayair.doctor.ui.inquiry_record;

import android.content.Context;
import android.content.SharedPreferences;
import android.text.TextUtils;
import android.util.Log;

import com.bayair.doctor.App;
import com.bayair.doctor.R;
import com.bayair.doctor.biz.im.ContactHelper;
import com.bayair.doctor.data.bean.ServerListResp;
import com.bayair.doctor.utils.log.KLog;
import com.tencent.imsdk.TIMConversation;
import com.tencent.imsdk.TIMConversationType;
import com.tencent.imsdk.TIMFriendshipManager;
import com.tencent.imsdk.TIMManager;
import com.tencent.imsdk.TIMMessage;
import com.tencent.imsdk.TIMRefreshListener;
import com.tencent.imsdk.TIMUserProfile;
import com.tencent.imsdk.TIMValueCallBack;
import com.tencent.imsdk.ext.message.TIMMessageLocator;
import com.tencent.imsdk.friendship.TIMFriend;
import com.tencent.qcloud.tim.uikit.modules.conversation.base.ConversationInfo;
import com.tencent.qcloud.tim.uikit.modules.conversation.interfaces.MessageUnreadWatcher;
import com.tencent.qcloud.tim.uikit.modules.message.MessageInfo;
import com.tencent.qcloud.tim.uikit.modules.message.MessageInfoUtil;
import com.tencent.qcloud.tim.uikit.modules.message.MessageRevokedManager;
import com.tencent.qcloud.tim.uikit.utils.SharedPreferenceUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 会话数据工具：负责对IM的会话数据操作，管理刷新、添加、删除...等数据操作，
 并通过provider把数据变化更新的UI上
 */
public class SessionDataKit implements
        MessageRevokedManager.MessageRevokeHandler,
        TIMRefreshListener,
        SessionCallback {

    private static SessionDataKit instance = new SessionDataKit();

    private SessionDataKit() {
        init();
    }

    public static SessionDataKit instance() {
        return instance;
    }

    private final static String TAG = "SessionKit";
    private final static String SP_NAME = "top_conversion_list";
    private final static String TOP_LIST = "top_list";
    private final String SP_IMAGE = "conversation_group_face";

    //未读监听
    private List<MessageUnreadWatcher> mUnreadWatchers = new ArrayList<>();
    //会话sp
    private SharedPreferences mConversationPreferences;
    //置顶数据list(使用linkedList排序)
    private LinkedList<ConversationInfo> mTopLinkedList = new LinkedList<>();

    private void init() {
        mConversationPreferences = App.getContext().getSharedPreferences(TIMManager.getInstance().getLoginUser() + SP_NAME, Context.MODE_PRIVATE);
        mTopLinkedList = SharedPreferenceUtils.getListData(mConversationPreferences, TOP_LIST, ConversationInfo.class);
        MessageRevokedManager.getInstance().addHandler(this);//监听消息撤回
    }

    private SessionCallback mCallback;
    private List<ConversationInfo> dataSource;

    public void loadConversation(SessionCallback callBack) {
        this.mCallback = callBack;

        //获取所有会话
        List<TIMConversation> timConversations = TIMManager.getInstance().getConversationList();
        /**
         TIMConversation会话转ConversationInfo
         */
        ArrayList<ConversationInfo> dataSource = new ArrayList<>();
        for (int i = 0; i < timConversations.size(); i++) {
            TIMConversation timConversation = timConversations.get(i);
            ConversationInfo conversationInfo = timConversation2ConversationInfo(timConversation);
            if (conversationInfo != null) {
                conversationInfo.setType(ConversationInfo.TYPE_COMMON); //
                dataSource.add(conversationInfo);
            }
        }
        //排序
        List<ConversationInfo> sortInfoList = sortConversations(dataSource);
        setList(sortInfoList);
    }


    /**
     TIMConversation会话转ConversationInfo信息

     @param conversation
     @return
     */
    private ConversationInfo timConversation2ConversationInfo(TIMConversation conversation) {
        if (conversation == null) {
            return null;
        }
        TIMMessage message = conversation.getLastMsg();
        if (message == null) {
            return null;
        }
        final ConversationInfo info = new ConversationInfo();
        //最后一条消息时间
        info.setLastMessageTime(message.timestamp());
        //获取会话类型
        TIMConversationType type = conversation.getType();
        boolean isGroup = type == TIMConversationType.Group;

        List<MessageInfo> list = MessageInfoUtil.TIMMessage2MessageInfo(message, isGroup);
        if (list != null && list.size() > 0) {
            //设置最后消息
            info.setLastMessage(list.get(list.size() - 1));
        }

        //设置获取标题、头像
        if (isGroup) {
            //fillConversationWithGroupInfo(conversation, info);
        } else {
            fillConversationWithUserProfile(conversation, info);
        }
        //设置会话id
        info.setId(conversation.getPeer());

        //设置是否服务中
        boolean valid = ContactHelper.isValid(patients, conversation.getPeer());
        info.setInServer(valid);

        //设置是否为群会话
        info.setGroup(conversation.getType() == TIMConversationType.Group);
        //设置未读消息计数
        if (conversation.getUnreadMessageNum() > 0) {
            info.setUnRead((int) conversation.getUnreadMessageNum());
        }
        return info;
    }

    /**
     获取用户信息填充到会话对象中（title、url）标题、头像
     */
    private void fillConversationWithUserProfile(TIMConversation conversation, ConversationInfo info) {
        String title = conversation.getPeer();
        final ArrayList<String> ids = new ArrayList<>();
        ids.add(conversation.getPeer());

        //获取本地好友资料（不包括：备注，好友分组），没有则返回 null
        TIMUserProfile profile = TIMFriendshipManager.getInstance().queryUserProfile(conversation.getPeer());
        if (profile == null) {
            TIMFriendshipManager.getInstance().getUsersProfile(ids, false, new TIMValueCallBack<List<TIMUserProfile>>() {
                @Override
                public void onError(int code, String desc) {
                    KLog.e(TAG, "getUsersProfile failed! code: " + code + " desc: " + desc);
                }

                @Override
                public void onSuccess(List<TIMUserProfile> timUserProfiles) {
                    if (timUserProfiles == null || timUserProfiles.size() != 1) {
                        KLog.i(TAG, "No TIMUserProfile");
                        return;
                    }
                    TIMUserProfile profile = timUserProfiles.get(0);
                    List<Object> face = new ArrayList<>();
                    if (profile != null && !TextUtils.isEmpty(profile.getFaceUrl())) {
                        face.add(profile.getFaceUrl());
                    } else {
                        face.add(R.drawable.default_head);
                    }
                    String title = conversation.getPeer();
                    if (profile != null && !TextUtils.isEmpty(profile.getNickName())) {
                        title = profile.getNickName();
                    }
                    info.setTitle(title);
                    info.setIconUrlList(face);

                    //更新单个会话属性
                    update(info);
                }
            });
        } else {
            List<Object> face = new ArrayList<>();
            if (!TextUtils.isEmpty(profile.getNickName())) {
                title = profile.getNickName();
            }
            if (TextUtils.isEmpty(profile.getFaceUrl())) {
                face.add(R.drawable.default_head);
            } else {
                face.add(profile.getFaceUrl());
            }
            info.setTitle(title);
            info.setIconUrlList(face);
        }

        //通过获取好友资料（不包括：备注，好友分组），如果有备注就设置为会话名称
        TIMFriend friend = TIMFriendshipManager.getInstance().queryFriend(conversation.getPeer());
        if (friend == null) {
            TIMFriendshipManager.getInstance().getFriendList(new TIMValueCallBack<List<TIMFriend>>() {
                @Override
                public void onError(int code, String desc) {
                    KLog.e(TAG, "getFriendList failed! code: " + code + " desc: " + desc);
                }

                @Override
                public void onSuccess(List<TIMFriend> timFriends) {
                    if (timFriends == null || timFriends.size() == 0) {
                        KLog.i(TAG, "No Friends");
                        return;
                    }
                    for (TIMFriend friend : timFriends) {
                        if (!TextUtils.equals(conversation.getPeer(), friend.getIdentifier())) {
                            continue;
                        }
                        if (TextUtils.isEmpty(friend.getRemark())) {
                            continue;
                        }
                        info.setTitle(friend.getRemark());

                        //更新单个会话属性
                        update(info);
                        return;
                    }
                    KLog.i(TAG, conversation.getPeer() + " is not my friend");
                }
            });
        } else {
            if (!TextUtils.isEmpty(friend.getRemark())) {
                title = friend.getRemark();
                info.setTitle(title);
            }
        }
    }

    /**
     消息撤回回调

     @param locator
     */
    @Override
    public void handleInvoke(TIMMessageLocator locator) {
        Log.d(TAG, "消息撤回 handleInvoke: " + locator);
        //消息撤回处理，刷新一下
        if (mCallback != null) {
            loadConversation(null);
        }
    }

    @Override
    public void onRefresh() {

    }

    @Override
    public void onRefreshConversation(List<TIMConversation> conversations) {
        Log.d("aaaa", "刷新会话: " + conversations.toString());
        ArrayList<ConversationInfo> infos = new ArrayList<>();
        for (int i = 0; i < conversations.size(); i++) {
            TIMConversation conversation = conversations.get(i);
            KLog.i(TAG, "onRefreshConversation TIMConversation " + conversation.toString());
            ConversationInfo conversationInfo = timConversation2ConversationInfo(conversation);
            if (conversationInfo != null) {
                infos.add(conversationInfo);
            }
        }
        if (infos.size() == 0) {
            return;
        }

        List<ConversationInfo> dataSource = this.dataSource;
        ArrayList exists = new ArrayList();
        for (int j = 0; j < infos.size(); j++) {
            ConversationInfo update = infos.get(j);

            if (dataSource == null) {
                return;
            }
            //之前会话遍历
            for (int i = 0; i < dataSource.size(); i++) {
                ConversationInfo cacheInfo = dataSource.get(i);
                //单个会话刷新时找到老的会话数据，替换
                if (cacheInfo.getId().equals(update.getId())) {
                    dataSource.remove(i);
                    dataSource.add(i, update);
                    exists.add(update);
                    break;
                }
            }
        }
        infos.removeAll(exists);
        if (infos.size() > 0) {
            dataSource.addAll(infos);
        }

        setList(sortConversations(dataSource));
        SharedPreferenceUtils.putListData(mConversationPreferences, TOP_LIST, mTopLinkedList);
    }

    /**
     会话数据排序，添加了置顶标识的处理

     @param sources
     @return
     */
    private List<ConversationInfo> sortConversations(List<ConversationInfo> sources) {
        ArrayList<ConversationInfo> conversationInfos = new ArrayList<>();
        List<ConversationInfo> normalConversations = new ArrayList<>();
        List<ConversationInfo> topConversations = new ArrayList<>();

        for (int i = 0; i <= sources.size() - 1; i++) {
            ConversationInfo conversation = sources.get(i);
            if (isTop(conversation.getId())) {
                conversation.setTop(true);
                topConversations.add(conversation);
            } else {
                normalConversations.add(conversation);
            }
        }

        mTopLinkedList.clear();
        mTopLinkedList.addAll(topConversations);
        Collections.sort(topConversations); // 置顶会话列表页也需要按照最后一条时间排序，由新到旧，如果旧会话收到新消息，会排序到前面
        conversationInfos.addAll(topConversations);
        Collections.sort(normalConversations); // 正常会话也是按照最后一条消息时间排序，由新到旧
        conversationInfos.addAll(normalConversations);
        return conversationInfos;
    }

    private boolean isTop(String id) {
        if (mTopLinkedList == null || mTopLinkedList.size() == 0) {
            return false;
        }
        for (ConversationInfo info : mTopLinkedList) {
            if (TextUtils.equals(info.getId(), id)) {
                return true;
            }
        }
        return false;
    }

    //--------------------会话操作（置顶、删除、添加）-----------------------------------------------------------

    /**
     将某个会话置顶（在会话界面调用）
     */
    public void setConversationTop(int index, ConversationInfo conversation) {
        KLog.i(TAG, "setConversationTop index:" + index + "|conversation:" + conversation);
        if (!conversation.isTop()) {
            mTopLinkedList.remove(conversation);
            mTopLinkedList.addFirst(conversation);
            conversation.setTop(true);
        } else {
            conversation.setTop(false);
            mTopLinkedList.remove(conversation);
        }
        setList(sortConversations(dataSource));
        SharedPreferenceUtils.putListData(mConversationPreferences, TOP_LIST, mTopLinkedList);
    }

    /**
     会话置顶操作（个人资料页面）

     @param id   会话ID
     @param flag 是否置顶
     */
    public void setConversationTop(String id, boolean flag) {
        KLog.i(TAG, "setConversationTop id:" + id + "|flag:" + flag);
        handleTopData(id, flag);
        setList(sortConversations(dataSource));
        SharedPreferenceUtils.putListData(mConversationPreferences, TOP_LIST, mTopLinkedList);
    }

    /**
     会话置顶的本地储存操作，目前用SharePreferences来持久化置顶信息

     @param id
     @param flag
     */
    private void handleTopData(String id, boolean flag) {
        ConversationInfo conversation = null;
        List<ConversationInfo> conversationInfos = dataSource;
        for (int i = 0; i < conversationInfos.size(); i++) {
            ConversationInfo info = conversationInfos.get(i);
            if (info.getId().equals(id)) {
                conversation = info;
                break;
            }
        }
        if (conversation == null) {
            return;
        }
        if (flag) {
            if (!isTop(conversation.getId())) {
                mTopLinkedList.remove(conversation);
                mTopLinkedList.addFirst(conversation);
                conversation.setTop(true);
            } else {
                return;
            }
        } else {
            if (isTop(conversation.getId())) {
                conversation.setTop(false);
                mTopLinkedList.remove(conversation);
            } else {
                return;
            }
        }
        SharedPreferenceUtils.putListData(mConversationPreferences, TOP_LIST, mTopLinkedList);
    }


    /**
     删除会话，会将本地会话数据从imsdk中删除

     @param index        在数据源中的索引
     @param conversation 会话信息
     */
    public void deleteConversation(int index, ConversationInfo conversation) {
        KLog.i(TAG, "deleteConversation index:" + index + "|conversation:" + conversation);
        boolean status = TIMManager.getInstance().deleteConversation(conversation.isGroup() ? TIMConversationType.Group : TIMConversationType.C2C, conversation.getId());
        KLog.i(TAG, status);
        if (status) {
            handleTopData(conversation.getId(), false);
            if (dataSource.remove(index) != null) {
                update(null);
            }
        }
    }

    /**
     删除会话，只删除数据源中的会话信息

     @param id 会话id
     */
    public void deleteConversation(String id, boolean isGroup) {
        KLog.i(TAG, "deleteConversation id:" + id + "|isGroup:" + isGroup);
        handleTopData(id, false);
        List<ConversationInfo> conversationInfos = dataSource;
        if (dataSource == null) {
            return;
        }
        for (int i = 0; i < conversationInfos.size(); i++) {
            ConversationInfo info = conversationInfos.get(i);
            if (info.getId().equals(id)) {
                if (conversationInfos.remove(i) != null) {
                    update(null);
                }
                break;
            }
        }

        TIMManager.getInstance().deleteConversation(isGroup ? TIMConversationType.Group : TIMConversationType.C2C, id);
    }

    /**
     添加会话

     @param conversationInfo
     @return
     */
    public boolean addConversation(ConversationInfo conversationInfo) {
        List<ConversationInfo> conversationInfos = new ArrayList<>();
        conversationInfos.add(conversationInfo);
        if (conversationInfos.size() == 1) {
            ConversationInfo conversation = conversationInfos.get(0);
            for (int i = 0; i < dataSource.size(); i++) {
                if (dataSource.get(i).getId().equals(conversation.getId()))
                    return true;
            }
        }
        boolean flag = dataSource.addAll(conversationInfos);
        if (flag) {
            update(null);
        }
        return flag;
    }

    //------------------保存kit中服务属性----------------------------------------------------------
    /**
     在服务中患者（患者id对应会话id）
     */
    private List<ServerListResp.PatientsBean> patients;

    public void setListInServer(List<ServerListResp.PatientsBean> patients) {
        this.patients = patients;
    }

    //------------------更新数据到ui-------------------------------------------------------------

    //更新会话list(这里的会话内容不完整，因为im接口有的是回调，有的直接返回，直接返回的数据列表通过这个接口更新，
    // 回调返回的属性会直接修改list中元素，通过下面的方法 setSingle（）来刷新)
    @Override
    public void setList(List<ConversationInfo> data) {
        if (mCallback != null) {
            dataSource = data;
            mCallback.setList(dataSource);
        }
    }

    //更新单个会话
    @Override
    public void update(ConversationInfo info) {
        if (mCallback != null) {
            mCallback.update(info);
        }
    }
}